
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Date;


public class JDBCUtils {   
    private static String targetPath;//  = "D:\\SVN\\A01_ShanTou_XNJK\\A03_Code\\XNJK\\parseHWgsm\\gwpSubFiles"; // 需要解析的文件所存放的文件夹路径
    private static String tbNamePrefix;
    private static String lineSplitLaber ="\n";
    private static String cowSplitLaber ="\t";
    private static String encoding = "utf-8";
    private static String connectionStr;
    private static String user;
    private static String password;
      public static void main(String[] args) {             
          boolean flag = parseArgs(args);
         
          if(targetPath==null ){
              System.out.println("传入参数错误！请传入了文件路径!");
              return;
          }
          if(tbNamePrefix==null ){
              System.out.println("传入参数错误！请确定数据库建表前缀!");
              return;
          }
          if(connectionStr==null ){
              System.out.println("传入参数错误！请传入数据库连接字符串（ip:port/dbName）!");
              return;
          }
          if(user==null ){
              System.out.println("传入参数错误！请传入数据库用户名!");
              return;
          }
          if(password==null ){
              System.out.println("传入参数错误！请传入数据库登录密码!");
              return;
          }
          if(!flag){
              System.out.println("出入参数错误！");
              return;
             
          } 
          Connection con    = null;// 创建一个数据库连接
        try
        {
            Class.forName("oracle.jdbc.driver.OracleDriver");// 加载Oracle驱动程序
            System.out.println("开始尝试连接数据库！");
            String url = "jdbc:oracle:" + "thin:@"+connectionStr;
            con = DriverManager.getConnection(url, user, password);// 获取连接
            System.out.println("连接成功！");           
            Date dateStrat = new Date();
            String [] files = readFilesFromDir(targetPath);
            int fileCount = files.length;
            System.out.println(fileCount);
            if(fileCount<1){
                System.out.println("目标文件夹中未读取到文件");
                return;
            }          
            for(int i =0;i<fileCount;i++){
//              System.out.println(files[i]);
              try{
                  String [] fileArr = ParseOneFileToArr(targetPath+"\\"+files[i],lineSplitLaber);
                  parseOneArrToDB(tbNamePrefix+files[i],fileArr,con,cowSplitLaber);
                  System.out.println(targetPath+"\\"+files[i]+"入库结束");
              }catch(Exception e){
                  System.out.println(files[i] +" 入库失败 ！"+e.getMessage());
              }
            }
            System.out.println("开始时间："+dateStrat.toString());      
            System.out.println("结束时间："+new Date().toString());
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            try
            {
                if (con != null)
                    con.close();
                System.out.println("数据库连接已关闭！");
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    }
     
      public static String[] readFilesFromDir(String dirPath){
          File file = new File(dirPath);
          String [] fileList = {}; 
          if(!file.exists()){
              return fileList;
          }
          fileList = file.list();
          return fileList;
     }
      public static String[] ParseOneFileToArr(String filePath,String splitLaber){
          File file = new File(filePath);
          String[] fileLines = {};
          if(!file.exists()){
              System.out.println(filePath+"不存在");
              return fileLines;
          }
          System.out.println(filePath+"正在解析");          
          long filelength = file.length();  
          byte[] filecontent = new byte[(int) filelength];
          try {  
              FileInputStream in = new FileInputStream(file);  
              in.read(filecontent);  
              in.close();  
          } catch (FileNotFoundException e) {  
              e.printStackTrace();  
          } catch (IOException e) {  
              e.printStackTrace();  
          }  
          try {  
              String fileMsg =  new String(filecontent, encoding);  
              fileLines = fileMsg.split(splitLaber);
              System.out.println(filePath+"解析完成正在入库。。。");  
              return fileLines;
          } catch (UnsupportedEncodingException e) {  
              System.err.println("The OS does not support " + encoding);             
              System.out.println(filePath+"解析出错...");  
              return fileLines;  
          }  
      }
      //将一个数据安装指定的表名称在数据库中创建相应的表并且将数据插入到表中
      public static void parseOneArrToDB(String tableName,String[] fileArr,Connection con,String cowSplitLaber) throws SQLException{
          String crtTableSql;
          String insertSql;
          String valuesSql;
          String firstLine;
          String finalSql;  
          int cowsLength;
          if(fileArr.length<2){
              System.out.println(tableName+"中无数据！");
              return;
          }
          firstLine = fileArr[0];
          String [] cows = firstLine.split(cowSplitLaber);
          crtTableSql = "begin PUB_PKG.PROC_STS_CREATE_TABLE('"+tableName+"','";
          insertSql = "insert into "+tableName+" (";
          valuesSql = " ) values (";
          cowsLength = cows.length;
          for(int i=0;i<cowsLength;i++){
              crtTableSql +=(cows[i]+",");
              insertSql +=("\""+cows[i]+"\",");
              valuesSql +=("?,");
          }
          crtTableSql = crtTableSql.substring(0, crtTableSql.length()-1);
          crtTableSql +=("');end;");
          insertSql = insertSql.substring(0, insertSql.length()-1);
          valuesSql = valuesSql.substring(0, valuesSql.length()-1);
          finalSql = insertSql+ valuesSql+")";
//          System.out.println(crtTableSql);
//          System.out.println(finalSql);
          
          PreparedStatement crtTb = con.prepareStatement(crtTableSql);
          PreparedStatement preSql = con.prepareStatement(finalSql);
          crtTb.execute();
          int fileLines = fileArr.length;
          for(int i=1;i<fileLines;i++){
              String [] oneLine =  fileArr[i].split(cowSplitLaber);
              
                  for(int j =0;j<cowsLength;j++){
                      try{
                          preSql.setString(j+1, oneLine[j]);
                      }catch(ArrayIndexOutOfBoundsException e){  
                          preSql.setString(j+1,"");                                    
                    }      
                  }
                  preSql.addBatch();
                  if(i % 10000 == 0) {
                      preSql.executeBatch();
                  } 
                   
          }    
          preSql.executeBatch();
          if (preSql != null)
              preSql.close();
          if (crtTb != null)
              crtTb.close();
      }
      private static boolean parseArgs(String[] args) {
          for (int i = 0; i < args.length; i++) {
              if (args[i] == null) {
                  return false;                  
              }
              args[i] = args[i].trim();             
          }
          try {
              for (int i = 0; i < args.length; i++) {
                  String a = args[i];
                  if(a.equals("")){
                      System.out.println("传入参数不能为空！");
                      return false;
                  }
                  if (a.equals("-help")) {
                      printUsageAndExit();
                      return false;
                  }
                  switch (a) {
                      case "-targetPath":
                          targetPath = args[++i];
                          break;               
                      case "-tbNamePrefix":
                          tbNamePrefix = args[++i];
                          break;
                      case "-lineSplitLaber":
                          lineSplitLaber = args[++i];
                          break;
                      case "-cowSplitLaber":
                          cowSplitLaber = args[++i];
                          break;
                      case "-encoding":
                          encoding = args[++i];
                          break;
                      case "-connectionStr":
                          connectionStr = args[++i];
                          break;
                      case "-user":
                          user = args[++i];
                          break;
                      case "-password":
                          password = args[++i];
                          break;
                     default:break;
                          
                      }
                  }
              }catch(Exception e){
                  return false;
              }
              
          return true;
      }

    private static void printUsageAndExit() {
        System.out.println();
        System.out.println("支持以下选项：");
        System.out.println("-help : 打印帮助信息");
        System.out.println("-targetPath 设置需要解析文件夹");
        System.out.println("-tbNamePrefix 建表的前缀");
        System.out.println("-lineSplitLaber 行间的分隔符号 (默认\\n)");
        System.out.println("-cowSplitLaber 列分隔符号（默认 \\t）");
        System.out.println("-encoding 文件编码（默认utf-8）");
        System.out.println("-connectionStr 数据库连接 (ip:port/dbName)");
        System.out.println("-user 数据库登录名称");
        System.out.println("-password 数据库登录密码");

        
    }
}
